"use client";

import * as React from "react";

import { type TElement } from "platejs";

import { toUnitLess } from "@platejs/basic-styles";
import { FontSizePlugin } from "@platejs/basic-styles/react";
import { Minus, Plus } from "lucide-react";
import { KEYS } from "platejs";
import { useEditorPlugin, useEditorSelector } from "platejs/react";

import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/plate/ui/popover";
import { cn } from "@/lib/utils";

import { ToolbarButton } from "./toolbar";

const DEFAULT_FONT_SIZE = "16";

const FONT_SIZE_MAP = {
  h1: "36",
  h2: "24",
  h3: "20",
} as const;

const FONT_SIZES = [
  "8",
  "9",
  "10",
  "12",
  "14",
  "16",
  "18",
  "24",
  "30",
  "36",
  "48",
  "60",
  "72",
  "96",
] as const;

export function FontSizeToolbarButton() {
  const [inputValue, setInputValue] = React.useState(DEFAULT_FONT_SIZE);
  const [isFocused, setIsFocused] = React.useState(false);
  const { editor, tf } = useEditorPlugin(FontSizePlugin);

  const cursorFontSize = useEditorSelector((editor) =&gt; {
    const fontSize = editor.api.marks()?.[KEYS.fontSize];

    if (fontSize) {
      return toUnitLess(fontSize as string);
    }

    const [block] = editor.api.block&lt;TElement&gt;() || [];

    if (!block?.type) return DEFAULT_FONT_SIZE;

    return block.type in FONT_SIZE_MAP
      ? FONT_SIZE_MAP[block.type as keyof typeof FONT_SIZE_MAP]
      : DEFAULT_FONT_SIZE;
  }, []);

  const handleInputChange = () =&gt; {
    const newSize = toUnitLess(inputValue);

    if (
      Number.parseInt(newSize, 10) &lt; 1 ||
      Number.parseInt(newSize, 10) &gt; 100
    ) {
      editor.tf.focus();

      return;
    }
    if (newSize !== toUnitLess(cursorFontSize)) {
      tf.fontSize.addMark(`${newSize}px`);
    }

    editor.tf.focus();
  };

  const handleFontSizeChange = (delta: number) =&gt; {
    const newSize = Number(displayValue) + delta;
    tf.fontSize.addMark(`${newSize}px`);
    editor.tf.focus();
  };

  const displayValue = isFocused ? inputValue : cursorFontSize;

  return (
    <div>
      &lt;ToolbarButton onClick={() =&gt; handleFontSizeChange(-1)}&gt;
        &lt;Minus /&gt;
      &lt;/ToolbarButton&gt;

      &lt;Popover open={isFocused} modal={false}&gt;
        &lt;PopoverTrigger asChild&gt;
          <input> {
              setIsFocused(false);
              handleInputChange();
            }}
            onChange={(e) =&gt; setInputValue(e.target.value)}
            onFocus={() =&gt; {
              setIsFocused(true);
              setInputValue(toUnitLess(cursorFontSize));
            }}
            onKeyDown={(e) =&gt; {
              if (e.key === "Enter") {
                e.preventDefault();
                handleInputChange();
              }
            }}
            data-plate-focus="true"
            type="text"
          /&gt;
        &lt;/PopoverTrigger&gt;
        &lt;PopoverContent
          className="w-10 px-px py-1"
          onOpenAutoFocus={(e) =&gt; e.preventDefault()}
        &gt;
          {FONT_SIZES.map((size) =&gt; (
            &lt;button
              key={size}
              className={cn(
                "flex h-8 w-full items-center justify-center text-sm hover:bg-accent data-[highlighted=true]:bg-accent",
              )}
              onClick={() =&gt; {
                tf.fontSize.addMark(`${size}px`);
                setIsFocused(false);
              }}
              data-highlighted={size === displayValue}
              type="button"
            &gt;
              {size}
            &lt;/button&gt;
          ))}
        &lt;/PopoverContent&gt;
      &lt;/Popover&gt;

      &lt;ToolbarButton onClick={() =&gt; handleFontSizeChange(1)}&gt;
        &lt;Plus /&gt;
      &lt;/ToolbarButton&gt;
    </div>
  );
}
